#pragma once

#include <stddef.h>

#include <memory>

#include "api/video/video_frame.h"
#include "api/video/video_source_interface.h"
#include "media/base/video_adapter.h"
#include "media/base/video_broadcaster.h"
#include "rtc_base/synchronization/mutex.h"

namespace p2pms 
{


class CapturerVideoSource : public rtc::VideoSourceInterface<webrtc::VideoFrame> 
{
public:
	class FramePreprocessor 
	{
	public:
		virtual ~FramePreprocessor() = default;
		virtual webrtc::VideoFrame Preprocess(const webrtc::VideoFrame& frame) = 0;
	};

	~CapturerVideoSource() override;

	void AddOrUpdateSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink,
		const rtc::VideoSinkWants& wants) override;
	void RemoveSink(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink) override;
	void SetFramePreprocessor(std::unique_ptr<FramePreprocessor> preprocessor) 
	{
		webrtc::MutexLock lock(&m_lock);
		preprocessor_ = std::move(preprocessor);
	}
	void SetEnableAdaptation(bool enable_adaptation) 
	{
		webrtc::MutexLock lock(&m_lock);
		m_enable_adaptation = enable_adaptation;
	}
	void OnOutputFormatRequest(int width, int height, const absl::optional<int>& max_fps);

protected:
	void OnFrame(const webrtc::VideoFrame& frame);
	rtc::VideoSinkWants GetSinkWants();

private:
	void UpdateVideoAdapter();
	webrtc::VideoFrame MaybePreprocess(const webrtc::VideoFrame& frame);

	webrtc::Mutex m_lock;
	std::unique_ptr<FramePreprocessor> preprocessor_ RTC_GUARDED_BY(m_lock);
	bool m_enable_adaptation RTC_GUARDED_BY(m_lock) = true;
	rtc::VideoBroadcaster m_broadcaster;
	cricket::VideoAdapter m_video_adapter;
};

}  // namespace p2pms
